#include "CampaignViewDelegate.h"



#include <ItemModel.h>
#include <ItemReference.h>



#include <QLineEdit>
#include <QComboBox>



CampaignViewDelegate::CampaignViewDelegate(QObject *parent) :
    QItemDelegate(parent)
{
}



QWidget* CampaignViewDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    Q_UNUSED(option);
    if (!index.isValid()) return 0;

    int type = itemData(index, AbstractItem::CategoryData, Qt::EditRole).toInt();
    int field = index.column();

    if (type < 0) return 0;

    switch (type)
    {
    case ItemCategory_Group:
    case ItemCategory_Item:
        if (field != AbstractItem::NameData) return 0;
        return new QLineEdit(parent);

    case ItemCategory_Reference:
        if (field != ItemReference::RefData && field != ItemReference::TypeData) return 0;
        return new QComboBox(parent);
    }

    return 0;
}



void CampaignViewDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    if (!index.isValid() || !editor) return;

    int type = itemData(index, AbstractItem::CategoryData, Qt::EditRole).toInt();
    if (type < 0) return;

    switch (type)
    {
    case ItemCategory_Group:
    case ItemCategory_Item:
        {
            QLineEdit* le = qobject_cast<QLineEdit*>(editor);
            if (!le) return;
            le->setText(index.data(Qt::EditRole).toString());
            return;
        }
    case ItemCategory_Reference:
        // reference combo box generating is handled below
        break;
    default:
        return;
    }


    QComboBox* cb = qobject_cast<QComboBox*>(editor);
    if (!cb) return;


    int field = index.column();
    if (field == ItemReference::TypeData)
    {
        for (int refType = ItemReference::ReferenceType_FIRST; refType <= ItemReference::ReferenceType_LAST; refType++)
        {
            cb->addItem(ItemReference::typeName(refType), refType);
        }

        int curr = cb->findData(index.data(Qt::EditRole).toInt());
        if (curr < 0) return;

        cb->setCurrentIndex(curr);
        return;
    }


    if (field == ItemReference::RefData)
    {
        const QAbstractItemModel* model = index.model();
        if (!model) return;

        int refType = itemData(index, ItemReference::TypeData, Qt::EditRole).toInt();
        if (refType < 0) return;

        QModelIndex groupIndex = model->index(0, AbstractItem::IdData, QModelIndex());
        while (groupIndex.isValid())
        {
            QString groupName = itemData(groupIndex, AbstractItem::NameData, Qt::EditRole).toString();
            if (refType == ItemReference::GroupRef)
            {
                QVariant id = groupIndex.data(Qt::EditRole);
                cb->addItem(groupName, id);

                groupIndex = groupIndex.sibling(groupIndex.row()+1, groupIndex.column());
                continue;
            }

            QModelIndex itemIndex = groupIndex.child(0, AbstractItem::IdData);
            while (itemIndex.isValid())
            {
                QVariant id = itemIndex.data(Qt::EditRole).toString();
                QString name = QString("%1 (%2)").arg(itemData(itemIndex, AbstractItem::NameData, Qt::EditRole).toString()).arg(groupName);
                cb->addItem(name, id);

                itemIndex = itemIndex.sibling(itemIndex.row()+1, itemIndex.column());
            }

            groupIndex = groupIndex.sibling(groupIndex.row()+1, groupIndex.column());
        }

        return;
    }


}



void CampaignViewDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
    if (!editor || !model || !index.isValid()) return;

    int type = itemData(index, AbstractItem::CategoryData, Qt::EditRole).toInt();
    if (type < 0) return;

    QVariant value;
    switch (type)
    {
    case ItemCategory_Group:
    case ItemCategory_Item:
        {
            QLineEdit* le = qobject_cast<QLineEdit*>(editor);
            if (!le) return;

            value = le->text();
            break;
        }


    case ItemCategory_Reference:
        {
            QComboBox* cb = qobject_cast<QComboBox*>(editor);
            if (!cb) return;

            value = cb->itemData(cb->currentIndex());
            break;
        }

    default:
        return;
    }

    model->setData(index, value, Qt::EditRole);
}



QVariant CampaignViewDelegate::itemData(const QModelIndex &baseIndex, const int &type, const int &role) const
{
    if (!baseIndex.isValid()) return -1;

    QModelIndex index = baseIndex.sibling(baseIndex.row(), type);
    if (!index.isValid()) return -1;

    QVariant data = index.data(role);
    if (!data.isValid() || data.isNull()) return -1;

    return data;
}





